﻿#pragma once
#include<iostream>
#include<vector>
#include<time.h>


using std::cout;
using std::endl;

template<class T>
class ObjectPool {
private:
	char* _memory = nullptr;//指向内存块的指针
	int _leftByte = 0;//内存块的剩余字节大小
	void* _freeList = nullptr;//管理还回来的对象的自由链表
public:
	T* New()
	{
		T* obj = nullptr;
		if (_freeList)//如果有直接取
		{
			obj = (T*)_freeList;
			//头删
			_freeList = *(void**)_freeList;
		}
		else {
			if (_leftByte < sizeof(T))
			{
				_leftByte = 128 * 1024;
				//_memory = (char*)malloc(_leftByte);
				_memory = (char*)SystemAlloc(_leftByte >> 13);
				if (!_memory)
				{
					throw std::bad_alloc();
				}
			}
			obj = (T*)_memory;
			// 使⽤定位new调⽤T的构造函数初始化
			new(obj)T;
			size_t objSize = sizeof(T) < sizeof(void*) ? sizeof(void*) : sizeof(T);
			_memory += objSize;
			_leftByte -= objSize;
		}
		return obj;

	}

	void Delete(T* obj)
	{
		// 显⽰调⽤的T的析构函数进⾏清理
		obj->~T();
		//头插
		*(void**)obj = _freeList;//32位下obj指向的前四个字节指向下一个T对象的地址
		_freeList = obj;
	}
		
};
//
//struct TreeNode
//{
//	int _val;
//	TreeNode* _left;
//	TreeNode* _right;
//	TreeNode()
//		:_val(0)
//		, _left(nullptr)
//		, _right(nullptr)
//	{}
//};
//void TestObjectPool()
//{
//	 申请释放的轮次
//	const size_t Rounds = 3;
//	 每轮申请释放多少次
//	const size_t N = 100000;
//	size_t begin1 = clock(); 
//	std::vector<TreeNode*> v1; 
//	v1.reserve(N);
//	for (size_t j = 0; j < Rounds; ++j)
//	{
//		for (int i = 0; i < N; ++i)
//		{
//			v1.push_back(new TreeNode);
//		}
//		for (int i = 0; i < N; ++i)
//		{
//			delete v1[i];
//		}
//		v1.clear();
//	}
//	size_t end1 = clock();
//	ObjectPool<TreeNode> TNPool; 
//	size_t begin2 = clock();
//	std::vector<TreeNode*> v2; 
//	v2.reserve(N);
//	for (size_t j = 0; j < Rounds; ++j)
//	{
//		for (int i = 0; i < N; ++i)
//		{
//			v2.push_back(TNPool.New());
//		}
//		for (int i = 0; i < 100000; ++i)
//		{
//			TNPool.Delete(v2[i]);
//		}
//		v2.clear();
//	}
//	size_t end2 = clock();
//	cout << "new cost time:" << end1 - begin1 << endl;
//	cout << "object pool cost time:" << end2 - begin2 << endl;
//}